package com.tin.handler;

import com.tin.bean.Audience;
import com.tin.bean.TokenInfo;
import com.tin.exception.ServiceRuntimeException;
import com.tin.service.UserService;
import com.tin.util.DateUtil;
import com.tin.util.JwtUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sound.midi.Soundbank;
import java.util.Date;

/**
 * @author liming_oicq@163.com
 * @date 2018-10-13 01:51
 * JWT拦截器，API调用前判断token是否有效
 */

@Component
//如果已经在WebConfiguration中加载了，这里可以不使用@Component
public class JWTInterceptor implements HandlerInterceptor {

    @Autowired
    private Audience audience;

    @Autowired
    private TokenInfo tokenInfo;

    @Autowired
    private UserService userService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        final String authHeader = request.getHeader("authorization");
        //如果请求路径中包括swagger则返回true，不验证token
        if (request.getServletPath().contains("swagger"))
            return true;

        //判断token是否有效
        if ("OPTIONS".equals(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
            return true;
        } else {
            if (null == authHeader || !authHeader.startsWith("bearer;")) {
                throw new ServiceRuntimeException("1004", "错误的token或token为null");

            }
        }
        final String token = authHeader.substring(7);
        try {
            final Claims claims = JwtUtil.parseJWT(token, audience.getBase64Secret());
            if (claims == null) {
                throw new ServiceRuntimeException("1004", "错误的token");
            }
            request.setAttribute("CLAIMS", claims);

            //判断token是否过期，如果过期，将tokenInfo从数据库删除
            Date now = new Date();
            Date expireDate = DateUtil.parse(tokenInfo.getExpireDate());
            if (now.compareTo(expireDate)>0) {
                userService.deleteByToken(tokenInfo.getToken());
                throw new ServiceRuntimeException("1004", "超时，请重新登录");
            }
            //如果token没过期，每一次请求token要延期
            long expMillis = now.getTime() + audience.getExpiresSecond() * 1000;
            tokenInfo.setExpireDate(DateUtil.format(new Date(expMillis)));
            System.out.println("=======" + tokenInfo.toString());
            userService.updateExpireDateByToken(tokenInfo.getExpireDate(), tokenInfo.getToken());
            return true;
            }catch (final Exception e) {
                throw new ServiceRuntimeException("1004", "登录信息错误");
        }

    }
}
